package com.virjar.xposedhooktool.tool.newsocket;

import android.support.annotation.NonNull;
import android.util.Log;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.io.OutputStream;

/**
 * Created by virjar on 2018/4/27.
 */

public class ChunckedInputStreamAggregator extends OutputStream {
    private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    private static final int CHUNK_LEN = 1;
    private static final int CHUNK_DATA = 2;
    private static final int CHUNK_INVALID = Integer.MAX_VALUE;

    private static final int BUFFER_SIZE = 2048;

    private static final String tag = "ChunckedInputStreamAggregator";


    private int state = CHUNK_LEN;

    /**
     * The chunk size
     */
    private int chunkSize;

    /**
     * The current position within the current chunk
     */
    private int pos;

    /**
     * True if we've reached the end of stream
     */
    private boolean eof = false;

    /**
     * True if this stream is closed
     */
    private boolean closed = false;

    public boolean isCompleted() {
        return false;
    }

    private byte[] chunckedHeaderLineBuffer = new byte[64];
    private int headerLineBufferEndPos = 0;

    @Override
    public synchronized void write(int b) throws IOException {
        if (state == CHUNK_LEN) {
            //在chunck的头部状态，需要解析chunk的大小
            if (headerLineBufferEndPos == chunckedHeaderLineBuffer.length) {
                throw new IOException("Bad chunk header,header length must less:" + chunckedHeaderLineBuffer.length);
            }
            chunckedHeaderLineBuffer[headerLineBufferEndPos++] = (byte) b;
            parseChunckHeader();
        }

    }

    @Override
    public synchronized void write(@NonNull byte[] b, int off, int len) throws IOException {
        if (state == CHUNK_LEN) {
            if (headerLineBufferEndPos == chunckedHeaderLineBuffer.length) {
                throw new IOException("Bad chunk header,header length must less:" + chunckedHeaderLineBuffer.length);
            }
            int dataLength = Math.min(len, chunckedHeaderLineBuffer.length - headerLineBufferEndPos);
            System.arraycopy(b, off, chunckedHeaderLineBuffer, headerLineBufferEndPos, dataLength);
            headerLineBufferEndPos += dataLength;
            int lineEnd = parseChunckHeader();

        }
        if (state == CHUNK_DATA) {

        }
    }



    private int parseChunckHeader() {
        int lineEnd = HttpStreamUtil.findLineEnd(chunckedHeaderLineBuffer, headerLineBufferEndPos);
        if (lineEnd < 0) {
            return lineEnd;
        }
        String line = new String(chunckedHeaderLineBuffer, 0, lineEnd - 2);
        int separator = line.indexOf(';');
        if (separator < 0) {
            separator = line.length();
        }
        try {
            chunkSize = Integer.parseInt(StringUtils.trim(line.substring(0, separator)), 16);
            state = CHUNK_DATA;
            pos = 0;
            if (chunkSize == 0) {
                eof = true;
            }
        } catch (final NumberFormatException e) {
            state = CHUNK_INVALID;
            Log.e("tag", "Bad chunk header", e);
        }
        return lineEnd;
    }
}
